package com.thd.springboottest.security.securitycustom;


import com.thd.springboottest.security.entity.Permissions;
import com.thd.springboottest.security.entity.User;
import com.thd.springboottest.security.service.UserService;
import com.thd.springboottest.security.utils.JwtTokenUtil;
import com.thd.springboottest.security.utils.R;
import com.thd.springboottest.security.utils.ServletUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * com.thd.springboottest.security.securitycustom.TokenFilter
 *
 * @author: wanglei62
 * @DATE: 2022/6/23 11:12
 **/
public class JwtTokenFilter extends OncePerRequestFilter {

    private UserService userService;

    public JwtTokenFilter(UserService userService){
        this.userService = userService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        if (!licenseData.getTarget().equals("ego")) {
//            String errorMessage = "服务器异常, error code: 1";
//            log.error(errorMessage);
//            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, errorMessage);
//            return;
//        }
//        if (System.currentTimeMillis() > licenseData.getExpAt()) {
//            String errorMessage = "服务器异常, error code: 2";
//            log.error(errorMessage);
//            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, errorMessage);
//            return;
//        }

        System.out.println("jwttoken过滤器处理");
        String token = request.getHeader("mytoken");

        if (null == token || "".equals(token.trim())) {
            token = request.getParameter("mytoken");
        }
        try {
            if (token != null) {

                String username = "";
                try{
                    Claims claims = JwtTokenUtil.getInstance().getAllClaimsFromToken(token);
                    username=claims.getSubject();
                }catch(ExpiredJwtException e){
                    ServletUtils.getInstance().failure(response,R.failure("JWT Token过期"));
                    return;
                }catch(Exception e){
//                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
                    ServletUtils.getInstance().failure(response,R.failure("JWT Token解析error"));
                    return;
                }




//                User user = this.userService.loadUserByAccount(token);
                User user = this.userService.loadUserByAccount(username);
                if(null!=user){
                    // 角色和权限
                    String roleStr = user.getRoles().stream().map(item -> {return item.getRoleName();}).collect(Collectors.joining(","));
                    String perms = user.getRoles().stream().map( item -> {
                        Set<Permissions> permList = item.getPermissions();
                        return permList.stream().map( Permissions::getPermissionsName ).collect(Collectors.joining(","));
                    }).collect(Collectors.joining(","));
                    String authorizes = roleStr + "," + perms;
                    System.out.println("权限："  + authorizes);
                    JwtToken jwtToken = new JwtToken(user,token, AuthorityUtils.commaSeparatedStringToAuthorityList(authorizes));


                    // !!!! 设置的jwtToken的anthenticated=true就代表通过了springsecurity的认证了
                    jwtToken.setAuthenticated(true);
                    SecurityContextHolder.getContext().setAuthentication(jwtToken);


                    System.out.println("jwttoken过滤器已获得认证");
                }

            }
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
        }

    }
}
